package com.sky.handler;

import com.sky.constant.MessageConstant;
import com.sky.exception.BaseException;
import com.sky.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.net.ConnectException;
import java.sql.SQLIntegrityConstraintViolationException;

/**
 * 全局异常处理器，处理项目中抛出的业务异常
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 捕获全局业务异常
     * @param ex 自定义继承运行时异常的异常
     * @return 异常信息
     */
    @ExceptionHandler
    public Result<String> exceptionHandler(BaseException ex){
        log.error("异常信息：{}", ex.getMessage());
        return Result.error(ex.getMessage());
    }

    /**
     * 捕获用户名重复插入数据库异常
     * @param ex SQL 完整性约束冲突异常
     * @return <重复数据的名称>已存在提示信息或未知错误+错误信息
     */
    @ExceptionHandler
    public Result<String> exceptionHandler(SQLIntegrityConstraintViolationException ex){
        //Duplicate entry 'lisan' for key 'employee.idx_username'
        String message = ex.getMessage();
        log.error("SQL信息:{}" , ex.getMessage());
        if (message.contains("Duplicate entry")){
            String[] split = message.split(" ");        //使用空格进行分隔开
            String repeatData = split[2];
            log.error("重复的数据库插入信息:{}" , repeatData);
            return Result.error(repeatData + MessageConstant.ALREADY_EXISTS);
        }
        return Result.error(MessageConstant.UNKNOWN_ERROR + ex.getMessage());
    }

    /**
     * 要上传的文件过大，大于了10MB
     * @param ex 超出文件大小限制异常
     * @return 要上传的文件过大提示信息或未知错误+错误信息
     */
    @ExceptionHandler
    public Result<String> exceptionHandler(FileSizeLimitExceededException ex){
        //org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException: The field file exceeds its maximum permitted size of 1048576 bytes
        String message = ex.getMessage();
        log.error("报错文件上传信息:{}" , ex.getMessage());
        if (message.contains("The field file exceeds its maximum")){
            return Result.error(MessageConstant.UPLOAD_TOOBIG);
        }
        return Result.error(MessageConstant.UNKNOWN_ERROR + ex.getMessage());
    }

    /**
     * 尝试进行复制属性时，用了空对象
     * @param ex 非法参数异常
     * @return 空对象尝试执行拷贝或未知错误+错误信息
     */
    @ExceptionHandler
    public Result<String> exceptionHandler(IllegalArgumentException ex){
        //java.lang.IllegalArgumentException: Source must not be null
        String message = ex.getMessage();
        log.error("进行了空对象copy:{}" , ex.getMessage());
        if (message.contains("Source must not be null")){
            return Result.error(MessageConstant.NULL_BEAN_COPY);
        }
        return Result.error(MessageConstant.UNKNOWN_ERROR + ex.getMessage());
    }

    /**
     * 连接redis数据库失败
     * @param ex 连接异常
     * @return 连接redis数据库失败
     */
    @ExceptionHandler
    public Result<String> exceptionHandler(ConnectException ex){
        //java.net.ConnectException: Connection refused: no further information
        String message = ex.getMessage();
        log.error("连接Redis数据库失败:{}" , ex.getMessage());
        if (message.contains("Connection refused")){
            return Result.error(MessageConstant.REDIS_CONNECTION_ERROR);
        }
        return Result.error(MessageConstant.UNKNOWN_ERROR + ex.getMessage());
    }

}
